package face.util;

import org.bytedeco.javacpp.opencv_core;
import org.bytedeco.javacpp.opencv_core.Mat;
import org.bytedeco.javacpp.opencv_core.Point2f;
import org.bytedeco.javacpp.opencv_core.Point2fVector;
import org.bytedeco.javacpp.opencv_imgproc;

/**
 * 人脸对齐
 * @author ShiQiang
 *
 */
public class Facealignment {
	
	public static Mat getwarpAffineImg(Mat src, Point2fVector landmarks) {    
		Mat oral = new Mat();
		src.copyTo(oral);     
//		for (int j = 0; j < landmarks.get().length; j++)     {        
//			opencv_imgproc.circle(oral, new Point((int) landmarks.get()[j].x(),(int) landmarks.get()[j].y()),2,new Scalar(255, 0, 0 ,0));     
//		} 
//		opencv_imgcodecs.imwrite("F:/2.jpg",oral);
		
		
		//计算两眼中心点，按照此中心点进行旋转， 第31个为左眼坐标，36为右眼坐标     
		//Point2f eyesCenter = new Point2f( (landmarks.get()[39].x() + landmarks.get()[42].x()) * 0.5f, (landmarks.get()[39].y() + landmarks.get()[42].y()) * 0.5f );          
		Point2f eyesCenter = new Point2f(landmarks.get()[27].x(), landmarks.get()[27].y());          

		// 计算两个眼睛间的角度    
		float dy = (landmarks.get()[42].y() - landmarks.get()[39].y());     
		float dx = (landmarks.get()[42].x() - landmarks.get()[39].x()); 
		
		double angle = Math.atan2(dy, dx) * 180.0/opencv_core.CV_PI;  
		// Convert from radians to degrees.          
		//由eyesCenter, andle, scale按照公式计算仿射变换矩阵，此时1.0表示不进行缩放     
		Mat rot_mat =opencv_imgproc.getRotationMatrix2D(eyesCenter, angle, 1.0);     
		Mat rot = new Mat();     
		// 进行仿射变换，变换后大小为src的大小    
		opencv_imgproc.warpAffine(src, rot, rot_mat, src.size());
		
//		PointVector marks = new PointVector();          
//		//按照仿射变换矩阵，计算变换后各关键点在新图中所对应的位置坐标。     
//		for (int n = 0; n<landmarks.get().length; n++)     {        
//			Point p =new Point(0, 0);         
//			p.x((int)(rot_mat.ptr(0).get(0)* landmarks.get()[n].x() + rot_mat.ptr(0).get(1) * landmarks.get()[n].y() + rot_mat.ptr(0).get(2))); 
//			p.y((int)(rot_mat.ptr(1).get(0)* landmarks.get()[n].x() + rot_mat.ptr(1).get(1) * landmarks.get()[n].y() + rot_mat.ptr(1).get(2)));         
//			marks.push_back(p);     
//		}     
		//标出关键点     
//		for (int j = 0; j < landmarks.get().length; j++)     {         
//				opencv_imgproc.circle(rot, marks.get(j), 2,new Scalar(0, 0, 255, 0));     
//		}    
//		opencv_imgcodecs.imwrite("F:/3.jpg",rot);
		
		return rot; 
	} 
}
